#pragma once

#include "stdafx.h"
#include <xstring>
#include "assert.h"
#include "hex.h"
#include "progress.h"
#include "structs.h"
#include "globals.h"
#include "strutil.h"

class CTable
{
public:
	CTable();
	~CTable();

	int Open(LPCTSTR name, bookmark *pbmkList, int &iBookmarkCount);
	void Open(TCHAR *fs, bookmark *pbmkList, int &iBookmarkCount);
	GString Save();

	void Reset();
	void translate(std::vector<_tstring>& data);
	void detranslate(std::vector<_tstring>& data);
	void enscript(std::vector<_tstring>& data);
	void descript(std::vector<_tstring>& data);
	//void read_script_file(fstream & fs, std::vector<std::string> & data);
	//void write_script_file(fstream & fs, std::vector<std::string> & data);
	//void pwrite_script_file(fstream & fs, std::vector<std::string> & data);
	//void convert_table_from_to(std::vector<_tstring>& x, std::vector<_tstring>& y);

	GString error;
	//std::vector<linkedvalue> vLinked;
	//std::vector<_tstring> vIMEBytes;
	std::vector<_tstring> vTableFileLeft;
	std::vector<_tstring> vTableFileRight;
	//std::vector<_tstring> vChanges;
	//std::vector<_tstring> vHighlights;
	std::vector<_tstring> vDTEs;
	//std::vector<bool> vbEmpty;
	std::vector<tablevalue> vMultiByteTableIn;
	std::vector<tablevalue> vMultiByteTableOut;
};

//void translate(std::vector<_tstring>& data);
//void detranslate(std::vector<_tstring>& data);
void enscript(std::vector<_tstring>& data);
//void descript(std::vector<_tstring>& data);
//void read_table_file(fstream& fs, HWND hwnd, bookmark *pbmkList, int &iBookmarkCount);
void read_table_file(TCHAR *fs, HWND hwnd, bookmark *pbmkList, int &iBookmarkCount);
void save_table_file(fstream& fs);
void read_script_file(fstream & fs, std::vector<std::string> & data);
void write_script_file(fstream & fs, std::vector<std::string> & data);
void pwrite_script_file(fstream & fs, std::vector<std::string> & data);
void convert_table_from_to(std::vector<_tstring>& x, std::vector<_tstring>& y);

static inline long dualtileindex(_tstring dualtile)
{
	return (unsigned char) dualtile[0] * 256 + (unsigned char) dualtile[1];
}

static inline long dualbyteindex(_tstring dualbyte)
{
	return (int) char_hex(dualbyte.substr(0,2)) * 256 + (int) char_hex(dualbyte.substr(2,2));
}

static inline long dualbyteindex(GString dualbyte)
{
	return dualbyteindex((_tstring)dualbyte);
}

static inline long toHIROM(long offset)
{
	return (offset - SNESHEADER) + 12582912;
}

static inline long fromHIROM(long offset)
{
	return (offset - 12582912) + SNESHEADER;
}

static inline long toLOROM(long offset)
{
	return (offset - SNESHEADER) + 32768;
}

static inline long fromLOROM(long offset)
{
	return (offset - 32768) + SNESHEADER;
}

static inline void insert_longest_to_shortest(std::vector<tablevalue>& x,tablevalue& y)
{
	if(x.size() == 0)
	{
		x.push_back(y);
		return;
	}
	if(x.size() == 1)
	{
		if(y.ascii.length() < x[0].ascii.length())
		{
			x.push_back(y);
		}
		else
		{
			//x.push_front(y);
			x.insert(x.begin(),y);
		}
		return;
	}
	else
	{
		int k = 0;
		for(k = 0;k<(int)x.size();k++)
		{
			if(!(y.ascii.length() < x[k].ascii.length()))
			{
				break;
			}
		}
		if(k == x.size())
		{
			x.push_back(y);

		}
		else
		{
			//x.insert(y,k);
			x.insert(x.begin()+k,y);
		}
		return;
	}
}

